namespace Launcher.View

import System
import System.Drawing
import System.Windows.Forms

import Launcher
import Launcher.Model
import Launcher.Ui

partial class LauncherView:
"""Create and setup the UI for this view"""

	public static final StartDistance	= 110
	public static final BorderSize		= 48

	_controls 	= []
	_buttons 	= []
	
	_circleRadius as int

	def InitializeUI(parent as Form):
		_shape = CircularFormShape(parent)
		
		_backBtn = Factory.CreateBackButton()
		_backBtn.Size = Drawing.Size(64, 64)
		_backBtn.Click += { OnBackClicked(EventArgs.Empty); BackPage() }
		_backBtn.VisibleChanged += { _parent.Invalidate() }
		_backBtn.SelectedChanged += { _parent.Invalidate() }
		
		_nextBtn = Factory.CreateNextButton()
		_nextBtn.Size = Drawing.Size(64, 64)
		_nextBtn.Click += { OnNextClicked(EventArgs.Empty); NextPage() }
		_nextBtn.VisibleChanged += { _parent.Invalidate() }
		_nextBtn.SelectedChanged += { _parent.Invalidate() }
		
		_closeBtn = Factory.CreateCloseButton()
		_closeBtn.Size = Drawing.Size(64, 64)
		_closeBtn.Click += { OnCloseClicked(EventArgs.Empty) } 
		_closeBtn.VisibleChanged += { _parent.Invalidate() }
		_closeBtn.SelectedChanged += { _parent.Invalidate() }
				
		_controls.Add(_backBtn)
		_controls.Add(_nextBtn)
		_controls.Add(_closeBtn)
		
		_filterBox = TextBox()
		_filterBox.TextChanged += { StartMenuModel.Instance.Filter = _filterBox.Text }
		parent.Controls.Add(_filterBox)
		
	def UpdateShape():
		return if len(_model.Pages) == 0
		radius = Organize()
		_shape.Radius = radius
		PositionUIButtons(radius)
		PositionFilter(radius)

	private def PositionUIButtons(radius as int):
		d = radius 
		midx = _parent.Size.Width  / 2
		midy = _parent.Size.Height / 2
		
		_backBtn.Location.X = midx - 32 - 64 - 16
		_backBtn.Location.Y = midy + d - 32 - 16

		_closeBtn.Location.X = midx - 32
		_closeBtn.Location.Y = midy + d - 32

		_nextBtn.Location.X = midx + 32 + 16
		_nextBtn.Location.Y = midy + d - 32 - 16

	private def PositionFilter(radius as int):
		midx = _parent.Size.Width  / 2
		midy = _parent.Size.Height / 2
		
		_filterBox.Location.X = midx - _filterBox.Size.Width / 2
		_filterBox.Location.Y = midy - radius - _filterBox.Size.Height / 4

	private def DrawControls(e as PaintEventArgs):
		for c as duck in _controls:
			c.Paint(self, e)

	private def DispatchControlsMouseClick(sender as object, e as MouseEventArgs):
		for c as CircularButton in _controls:
			if c.Contains(e.X, e.Y): c.OnClick(e)
		
	private def DispatchControlsMouseMove(sender as object, e as MouseEventArgs):
		_controls.Each() do(c as CircularButton):
			c.Selected = c.Contains(e.X, e.Y)
	
	private def Organize():
		positions = CalculatePositions()
		SetupIconsPositions(positions)
		return GetCircleRadius(positions)
		
	private def CalculatePositions():
		l = []
		level = 0
		distance = 0
		step = StartDistance
		arc = 0
		delta = 360
		
		for n as int, i in enumerate(_model.SelectedPage.Items):
			l.Add((level, distance, arc))
			
			if arc + delta >= 360 and n + 1 != len(_model.SelectedPage.Items):
				arc = 0
				level++
				delta = 360 / (_model.StartCount * level)
				distance += step
				step -= 10
			else:
				arc += delta
					
		return l

	private def SetupIconsPositions(positions as List):
		if len(_buttons) != len(positions):
			UpdateButtons(len(positions))
			
		_buttons[: len(positions)].Enumerate() do (i as int, b as IconButton):
			SetupIcon(b, _model.SelectedPage.Items[i], positions[i])
						
		_buttons[len(positions):].Each() do(i as IconButton):
			i.Visible = false

	private def UpdateButtons(length as int):
		if len(_buttons) < length:
			for i in range(length - len(_buttons)):
				_buttons.Add(c = IconButton(self, Visible: false))
				_parent.Controls.Add(c)

	private def SetupIcon(button as IconButton, item as LauncherItem, info as (int)):
		level, distance, arc = info
		x = _parent.Size.Width / 2 + distance*Math.Cos(arc*Math.PI / 180)
		y = _parent.Size.Height / 2 + distance*Math.Sin(arc*Math.PI / 180)
		size = 64 - level * 10
		
		button.Width = size * 1.5
		button.Height = size * 1.5
		button.Location.X = x - button.Width / 2
		button.Location.Y = y - button.Height / 2
		button.TargetItem = item
		button.Visible = true

	private def GetCircleRadius(items as List):
		if len(items) == 0:
			size = 300
		else:
			last as (int) = items[-1]
			size = last[1] + BorderSize
			
		_circleRadius = _circleRadius.Max(size).Max(300)
		return _circleRadius
	
	private _shape as CircularFormShape
	private _backBtn as CircularButton
	private _nextBtn as CircularButton
	private _closeBtn as CircularButton
	
	private _filterBox as TextBox
